package io.github.lee.jel.domain

import android.content.Context
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Parcelable
import android.util.Log
import android.widget.ImageView
import androidx.annotation.Keep
import androidx.databinding.BindingAdapter
import coil.load
import coil.request.ErrorResult
import coil.request.ImageRequest
import com.google.gson.annotations.SerializedName
import io.github.lee.jel.global.session
import io.github.lee.jel.repository.query.QueryIncludeItemType
import kotlinx.parcelize.Parcelize


fun ImageView.loadItemPrimary(
    item: Item?,
    crossfade: Int? = null,
    placeholder: Drawable? = null,
    error: Drawable? = null
) {
    this.load(item?.fullPrimaryImage(context)) {
        if (null != crossfade) {
            crossfade(true)
            crossfade(crossfade)
        }
        listener(object : ImageRequest.Listener {
            override fun onError(request: ImageRequest, result: ErrorResult) {
                Log.e("Error", "${request.data} load error : ${result.throwable}")
            }
        })
        if (null != placeholder) {
            placeholder(placeholder)
        }
        if (null != error) {
            error(error)
        }
    }
}


fun ImageView.loadItemBackdrop(
    item: Item?,
    crossfade: Int? = null,
    placeholder: Drawable? = null,
    error: Drawable? = null
) {
    this.load(item?.fullBackdropImage(context)) {
        if (null != crossfade) {
            crossfade(true)
            crossfade(crossfade)
        }
        listener(object : ImageRequest.Listener {
            override fun onError(request: ImageRequest, result: ErrorResult) {
                Log.e("Error", "${request.data} load error : ${result.throwable}")
            }
        })
        if (null != placeholder) {
            placeholder(placeholder)
        }
        if (null != error) {
            error(error)
        }
    }
}


fun ImageView.loadItemLogo(
    item: Item?,
    crossfade: Int? = null,
    placeholder: Drawable? = null,
    error: Drawable? = null
) {
    this.load(item?.fullLogoImage(context)) {
        if (null != crossfade) {
            crossfade(true)
            crossfade(crossfade)
        }
        listener(object : ImageRequest.Listener {
            override fun onError(request: ImageRequest, result: ErrorResult) {
                Log.e("Error", "${request.data} load error : ${result.throwable}")
            }
        })
        if (null != placeholder) {
            placeholder(placeholder)
        }
        if (null != error) {
            error(error)
        }
    }
}


fun ImageView.loadItemSeriesPrimary(
    item: Item?,
    crossfade: Int? = null,
    placeholder: Drawable? = null,
    error: Drawable? = null
) {
    this.load(item?.fullLogoImage(context)) {
        if (null != crossfade) {
            crossfade(true)
            crossfade(crossfade)
        }
        listener(object : ImageRequest.Listener {
            override fun onError(request: ImageRequest, result: ErrorResult) {
                Log.e("Error", "${request.data} load error : ${result.throwable}")
            }
        })
        if (null != placeholder) {
            placeholder(placeholder)
        }
        if (null != error) {
            error(error)
        }
    }
}

@BindingAdapter(
    value = ["loadItem", "crossfade_time", "placeholder_res", "error_res"],
    requireAll = false
)
fun ImageView.loadItem(
    item: Item?,
    crossfade: Int? = null,
    placeholder: Drawable? = null,
    error: Drawable? = null
) {
    this.post {
        this.measure(0, 0)
        val width = this.measuredWidth
        val height = this.measuredHeight
        Log.e("TAG", "width = $width, height = $height")
        if (width == height) {
            when (item?.type) {
                QueryIncludeItemType.Movie -> loadItemPrimary(item, crossfade, placeholder, error)
                QueryIncludeItemType.Episode -> loadItemSeriesPrimary(
                    item,
                    crossfade,
                    placeholder,
                    error
                )

                else -> loadItemPrimary(item, crossfade, placeholder, error)
            }

//            loadItemLogo(item, crossfade, placeholder, error)
        } else if (width > height) {
            loadItemBackdrop(item, crossfade, placeholder, error)
        } else {
            when (item?.type) {
                QueryIncludeItemType.Movie -> loadItemPrimary(item, crossfade, placeholder, error)
                QueryIncludeItemType.Episode -> loadItemSeriesPrimary(
                    item,
                    crossfade,
                    placeholder,
                    error
                )

                else -> loadItemPrimary(item, crossfade, placeholder, error)
            }

        }
    }

}

@Keep
@Parcelize
data class Item(
    @SerializedName("BackdropImageTags")
    val backdropImageTags: List<String?>? = null,
    @SerializedName("ChannelId")
    val channelId: String? = null,
    @SerializedName("CommunityRating")
    val communityRating: Double? = null,
    @SerializedName("Container")
    val container: String? = null,
    @SerializedName("HasSubtitles")
    val hasSubtitles: Boolean? = null,
    @SerializedName("Id")
    val id: String? = null,
    @SerializedName("CollectionType")
    val collectionType: String? = null,
    @SerializedName("ImageTags")
    val imageTags: ImageTags? = null,
    @SerializedName("IndexNumber")
    val indexNumber: Int? = null,
    @SerializedName("IsFolder")
    val isFolder: Boolean? = null,
    @SerializedName("LocationType")
    val locationType: String? = null,
    @SerializedName("MediaType")
    val mediaType: String? = null,
    @SerializedName("Name")
    val name: String? = null,
    @SerializedName("OfficialRating")
    val officialRating: String? = null,
    @SerializedName("ParentBackdropImageTags")
    val parentBackdropImageTags: List<String?>? = null,
    @SerializedName("ParentBackdropItemId")
    val parentBackdropItemId: String? = null,
    @SerializedName("ParentIndexNumber")
    val parentIndexNumber: Int? = null,
    @SerializedName("PremiereDate")
    val premiereDate: String? = null,
    @SerializedName("PrimaryImageAspectRatio")
    val primaryImageAspectRatio: Double? = null,
    @SerializedName("ProductionYear")
    val productionYear: Int? = null,
    @SerializedName("RunTimeTicks")
    val runTimeTicks: Long? = null,
    @SerializedName("SeasonId")
    val seasonId: String? = null,
    @SerializedName("SeasonName")
    val seasonName: String? = null,
    @SerializedName("SeriesId")
    val seriesId: String? = null,
    @SerializedName("SeriesName")
    val seriesName: String? = null,
    @SerializedName("SeriesPrimaryImageTag")
    val seriesPrimaryImageTag: String? = null,
    @SerializedName("ServerId")
    val serverId: String? = null,
    @SerializedName("Type")
    val type: QueryIncludeItemType? = null,
    @SerializedName("UserData")
    val userData: UserData? = null,
    @SerializedName("VideoType")
    val videoType: String? = null
) : Parcelable {

    fun runTimeTicksMillisecond():Long{
        val s = runTimeTicks.toString()
        val totalMinute = if (s.length == 11) {
            (runTimeTicks ?: 0) / 10
        } else {
            runTimeTicks ?: 0
        }
        return totalMinute / 1000L
    }

    fun fullPrimaryImage(context: Context): Uri? {
        if (null == imageTags) {
            return null
        }
        val primary = imageTags.primary
        if (primary.isNullOrEmpty()) {
            return null
        }
        return Uri.parse(context.session?.address).buildUpon()
            .appendEncodedPath("Items/$id/Images/Primary")
            .appendQueryParameter("tag", primary)
            .build()
    }


    fun fullBackdropImage(context: Context): Uri? {
        val tag = backdropImageTags?.firstOrNull()

        return Uri.parse(context.session?.address).buildUpon()
            .appendEncodedPath("Items/$id/Images/Backdrop")
            .appendQueryParameter("tag", tag)
            .build()

    }

    fun fullLogoImage(context: Context): Uri? =

        Uri.parse(context.session?.address).buildUpon()
            .appendEncodedPath("Items/$id/Images/Logo")
            .appendQueryParameter("tag", imageTags?.logo)
            .build()

    fun fullSeriesPrimary(context: Context): Uri? =
        Uri.parse(context.session?.address).buildUpon()
            .appendEncodedPath("Items/$seriesId/Images/Primary")
            .appendQueryParameter("tag", seriesPrimaryImageTag)
            .build()
}


@Keep
@Parcelize
data class ImageTags(
    @SerializedName("Primary")
    val primary: String? = null,
    @SerializedName("Logo")
    val logo: String? = null
) : Parcelable

@Keep
@Parcelize
data class UserData(
    @SerializedName("IsFavorite")
    val isFavorite: Boolean? = false,
    @SerializedName("ItemId")
    val itemId: String? = "",
    @SerializedName("Key")
    val key: String? = "",
    @SerializedName("LastPlayedDate")
    val lastPlayedDate: String? = "",
    @SerializedName("Likes")
    val likes: Boolean? = false,
    @SerializedName("PlayCount")
    val playCount: Int? = 0,
    @SerializedName("PlaybackPositionTicks")
    val playbackPositionTicks: Long? = 0,
    @SerializedName("Played")
    val played: Boolean? = false,
    @SerializedName("PlayedPercentage")
    val playedPercentage: Double? = 0.0,
    @SerializedName("Rating")
    val rating: Int? = 0,
    @SerializedName("UnplayedItemCount")
    val unplayedItemCount: Int? = 0
) : Parcelable
//@Keep
//@Parcelize
//data class UserData(
//    @SerializedName("IsFavorite")
//    val isFavorite: Boolean? = null,
//    @SerializedName("Key")
//    val key: String? = null,
//    @SerializedName("LastPlayedDate")
//    val lastPlayedDate: String? = null,
//    @SerializedName("PlayCount")
//    val playCount: Int? = null,
//    @SerializedName("PlaybackPositionTicks")
//    val playbackPositionTicks: Long? = null,
//    @SerializedName("Played")
//    val played: Boolean? = null,
//    @SerializedName("PlayedPercentage")
//    val playedPercentage: Double? = null
//) : Parcelable

